<template>
  <div style="height: 100%;" class="column">
    <div class="text-h6">{{ field.label }}</div>
    <div class="row" style="flex: 1;" ref="boxDetail">
      <div class="col-5">
        <q-table
          :rows="waitData"
          :columns="waitColumns"
          row-key="value"
          :selection="field.readonly ? 'none' : 'multiple'"
          v-model:selected="waitSelected"
          dense
          hide-bottom
          class="local-sticky-virtscroll-table"
          virtual-scroll
          :style="{ height: clientHeight }"
          v-show="clientHeight"
          @row-click="waitRowclick"
          :disabled="field.readonly"
          :rows-per-page-options="[0]"
        />
      </div>
      <div class="col-2 column items-center justify-center q-gutter-md">
        <q-btn dense color="primary" icon="keyboard_arrow_right" @click="selectItem" :disable="waitSelected.length < 1 || field.readonly" />
        <q-btn dense color="primary" icon="keyboard_arrow_left" @click="removeItem" :disable="selSelected.length < 1 || field.readonly" />
      </div>
      <div class="col-5">
        <q-table
          :rows="selectedData"
          :columns="selColumns"
          row-key="value"
          :selection="field.readonly ? 'none' : 'multiple'"
          v-model:selected="selSelected"
          dense
          hide-bottom
          class="local-sticky-virtscroll-table"
          virtual-scroll
          :style="{ height: clientHeight }"
          v-show="clientHeight"
          @row-click="selRowclick"
          :disabled="field.readonly"
          :rows-per-page-options="[0]"
        />
      </div>
    </div>
  </div>
</template>

<script>
import { defineComponent } from 'vue';
export default defineComponent({
  props: {
    field: {
      type: Object,
      default: () => []
    }
  },
  emits: ['change'],
  data () {
    return {
      clientHeight: null,
      waitSelected: [],
      waitColumns: [
        { name: 'label', label: this.field.leftLabel || '待选项', field: 'label', align: 'left' }
      ],
      selSelected: [],
      selColumns: [
        { name: 'label', label: this.field.rightLabel || '已选项', field: 'label', align: 'left' }
      ]
    }
  },
  mounted () {
    this.$nextTick(() => {
      this.resize();
    });
    const self = this;
    window.addEventListener('resize', function () {
      self.resize();
    });
  },
  methods: {
    resize () {
      if (this.$refs.boxDetail) {
        const element = window.getComputedStyle(this.$refs.boxDetail);
        const offsetHeight = `${element.getPropertyValue('height').replace(/px/g, '') - element.getPropertyValue('padding').replace(/px/g, '') * 2}px`;

        this.clientHeight = offsetHeight;
      }
    },
    selectItem () {
      if (this.waitSelected.length > 0) {
        const oldValue = this.field.value;
        this.field.value = [...new Set([...this.field.value.split(','), ...this.waitSelected.map(v => String(v.value))])].filter(v => !!v).join(',');
        const newValue = this.field.value;
        this.waitSelected = [];

        this.$emit('change', { newValue, oldValue, mode: 'add' });
      }
    },
    removeItem () {
      if (this.selSelected.length > 0) {
        const oldValue = this.field.value;
        const selArr = this.selSelected.map(v => String(v.value));
        this.field.value = this.field.value.split(',').filter(v => !!v && !selArr.includes(v)).join(',');
        const newValue = this.field.value;
        this.selSelected = [];

        this.$emit('change', { newValue, oldValue, mode: 'remove' });
      }
    },
    waitRowclick (evt, row) {
      if (this.field.readonly) return;

      const idx = this.waitSelected.findIndex(v => v.value == row.value);
      if (idx > -1) {
        this.waitSelected.splice(idx, 1);
      } else {
        this.waitSelected.push(row);
      }
    },
    selRowclick (evt, row) {
      if (this.field.readonly) return;

      const idx = this.selSelected.findIndex(v => v.value == row.value);
      if (idx > -1) {
        this.selSelected.splice(idx, 1);
      } else {
        this.selSelected.push(row);
      }
    }
  },
  computed: {
    waitData () {
      const data = [];

      if (this.field.options && this.field.options.length > 0) {
        const selArr = this.field.value.split(',').filter(v => !!v);
        const filArr = this.field.options.filter(v => !selArr.includes(String(v.value)));
        data.push(...filArr);
      }
      return data;
    },
    selectedData () {
      let data = this.field.value.split(',').filter(v => !!v);

      data = data.map(v => {
        const items = this.field.options.filter(opt => opt.value == v);
        if (items.length > 0) {
          return items[0];
        } else {
          return { value: v, label: v };
        }
      });

      return data;
    }
  }
});
</script>

<style lang="scss">
.local-sticky-virtscroll-table {
  thead tr:first-child th {
    background-color: $grey-4;
    text-align: center;
  }

  thead tr th {
    position: sticky;
    z-index: 1;
  }

  thead tr:last-child th {
    top: 48px;
  }

  thead tr:first-child th {
    top: 0;
  }
}
</style>
